﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

/* 曝光时间（转换后）=曝光时间（us）*0.75进行取整；
 * 每秒包数（转换后）=750000/每秒包数（单位为个）进行取整
 */
namespace FBGModelSetting
{
    public partial class frmFbgSetting : Form
    {
        //IP地址
        private IPAddress ipAddr = IPAddress.Parse("10.66.166.16");
        //发送端口号
        private int iSourcePort = 8001;
        //接收端口号
        private int iRemotePort = 8990;
        //曝光时间 iTick = (int)Math.Round(double.Parse(txtSTime.Text)*3d/4d,0);
        private byte iTick = 30;
        //每秒包数 iPackage = (int)Math.Round(750000/double.Parse(txtPNum.Text),0);
        private UInt16 iPackage = 500;

        //发送指令(类型+曝光时间+包数)
        private byte[] SenBytes = new byte[] { 0x5A, 0x5A, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xA5 };
        //接收指令(曝光时间+包数)
        private byte[] GetBytes = new byte[] { 0x5A, 0x5A, 0x00, 0x00, 0x00, 0xA5, 0xA5 };

        private Timer timer = null;
        
        private byte[] recBytes = null;

        private readonly Font readFont = new System.Drawing.Font("宋体", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point, ((byte)(134)));

        private void TransBuffer(byte[] bytes)
        {
            recBytes=null;
            UdpClient udp = new UdpClient(iSourcePort);
            IPEndPoint ipe = new IPEndPoint(IPAddress.Any, iSourcePort);
            try
            {
                udp.Connect(ipAddr, iRemotePort);
                udp.Client.ReceiveTimeout = 5000;
                udp.Send(bytes, bytes.Length);
                recBytes = udp.Receive(ref ipe);
                udp.Close();
                IsSuccessFlag = true;
            }
            catch 
            {
                IsSuccessFlag = false;
                if (udp != null)
                {
                    udp.Close();
                    udp = null;
                    ipe = null;
                }
            }
        }
        
        private bool IsSuccessFlag = true;
        private Timer tTick = null;

        public frmFbgSetting()
        {
            InitializeComponent();
            lblTime.Text = DateTime.Now.ToString();

            txtHost.Text = ipAddr.ToString();
            txtSendPort.Text = iSourcePort.ToString();
            txtRecPort.Text = iRemotePort.ToString();
            txtSTime.Text = string.Format("{0}",Math.Round(iTick*4d/3d,0));
            txtPNum.Text = string.Format("{0}",Math.Round(750000d/iPackage,0));
            txtHost.LostFocus += new EventHandler(txtHost_LostFocus);
            txtSendPort.LostFocus += new EventHandler(txtHost_LostFocus);
            txtRecPort.LostFocus += new EventHandler(txtHost_LostFocus);
            txtPNum.LostFocus += new EventHandler(txtHost_LostFocus);
            txtSTime.LostFocus += new EventHandler(txtHost_LostFocus);
            txtPNum.LostFocus += new EventHandler(txtHost_LostFocus);
            txtSTime.KeyPress += new KeyPressEventHandler(txtSTime_KeyPress);
            txtPNum.KeyPress += new KeyPressEventHandler(txtSTime_KeyPress);
            
            btnGet.Click += new EventHandler(btnGet_Click);
            btnSet.Click += new EventHandler(btnGet_Click);
            
            timer = new Timer();

            timer.Interval = 1000;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Enabled=true;

            backWorker = new BackgroundWorker();
            backWorker.DoWork += new DoWorkEventHandler(backWorker_DoWork);
            backWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backWorker_RunWorkerCompleted);

            tTick = new Timer();
            tTick.Interval = 3000;
            tTick.Enabled = false;
            tTick.Tick += new EventHandler(tTick_Tick);
            btnGet.Enabled = true;
            btnSet.Enabled = true;
        }

        void tTick_Tick(object sender, EventArgs e)
        {
            tTick.Enabled = false;
            btnGet.Enabled = true;
            btnSet.Enabled = true;
        }

        void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Button btn = e.Result as Button;
            byte[] getBytes = null;
            if (btn.Name == btnGet.Name)
            {
                try
                {
                    if (recBytes != null)
                    {
                        getBytes = (byte[])recBytes.Clone();
                    }
                    if (getBytes == null)
                    {
                        lblState.Text = string.Format("读取配置信息失败！");
                    }
                    else if (getBytes.Length != GetBytes.Length)
                    {
                        lblState.Text = string.Format("读取配置信息失败！");
                    }
                    else if ((BitConverter.ToInt16(getBytes, 0) != BitConverter.ToInt16(GetBytes, 0))
                        || (BitConverter.ToInt16(getBytes, 5) != BitConverter.ToInt16(GetBytes, 5)))
                    {
                        lblState.Text = string.Format("读取配置信息失败！");
                    }
                    else
                    {
                        iTick = getBytes[2];
                        iPackage = (UInt16)((getBytes[3] << 8) | (getBytes[4]));
                        txtSTime.Font = readFont;
                        txtPNum.Font = readFont; 
                        txtSTime.Text = string.Format("{0}", Math.Round(iTick * 4d / 3d, 0));
                        txtPNum.Text = string.Format("{0}", Math.Round(750000d / iPackage, 0));
                        lblState.Text = string.Format("配置信息读取成功！");
                    }
                }
                catch { }
            }
            if (btn.Name == btnSet.Name)
            {
                try
                {
                    if (recBytes != null)
                    {
                        getBytes = (byte[])recBytes.Clone();
                    }
                    if (getBytes == null)
                    {
                        lblState.Text = string.Format("设置配置信息失败！");
                    }
                    else if (getBytes.Length != GetBytes.Length)
                    {
                        lblState.Text = string.Format("设置配置信息失败！");
                    }
                    else if ((BitConverter.ToInt16(getBytes, 0) != BitConverter.ToInt16(GetBytes, 0))
                        || (BitConverter.ToInt16(getBytes, 5) != BitConverter.ToInt16(GetBytes, 5)))
                    {
                        lblState.Text = string.Format("设置配置信息失败！");
                    }
                    else if ((iTick != (int)getBytes[2])
                        || (iPackage != (UInt16)((getBytes[3] << 8) | (getBytes[4]))))
                    {
                        lblState.Text = string.Format("设置配置信息失败！");
                    }
                    else
                    {
                        iTick = getBytes[2];
                        iPackage = (UInt16)((getBytes[3] << 8) | (getBytes[4]));
                        txtSTime_KeyPress(txtSTime, null);
                        txtSTime_KeyPress(txtPNum, null);
                        txtSTime.Text = string.Format("{0}", Math.Round(iTick * 4d / 3d, 0));
                        txtPNum.Text = string.Format("{0}", Math.Round(750000d / iPackage, 0));
                        lblState.Text = string.Format("设置配置信息成功！");
                    }
                }
                catch { }
            }
            if (!IsSuccessFlag)
            {
                btnGet.Enabled = true;
                btnSet.Enabled = true;
            }
            else
            {
                tTick.Enabled = true;
            }    
        }

        void backWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            DateTime dt = DateTime.Now.AddSeconds(5);
            Button btn = e.Argument as Button;
            if (btn.Name == btnGet.Name)
            {
                try
                {
                    SenBytes[2] = 0xf0;
                    GetMessage gms = delegate(byte[] bytes)
                    {
                        TransBuffer(bytes);
                    };
                    IAsyncResult iaGet = gms.BeginInvoke(SenBytes, null, null);

                    iaGet.AsyncWaitHandle.WaitOne();
                }
                catch { }
            }
            if (btn.Name == btnSet.Name)
            {
                try
                {
                    SenBytes[2] = 0x00;
                    SenBytes[3] = byte.Parse(iTick.ToString());                
                    SenBytes[4] =(byte) ((iPackage >> 8) & 0xFF);
                    SenBytes[5] = (byte)(iPackage & 0xFF);
                    GetMessage gms = delegate(byte[] bytes)
                    {
                        TransBuffer(bytes);
                    };
                    IAsyncResult iaSet = gms.BeginInvoke(SenBytes, null, null);

                    iaSet.AsyncWaitHandle.WaitOne();
                }
                catch {}
            }
            TimeSpan ts = dt - DateTime.Now;
            int i = (int)ts.TotalMilliseconds;
            if (i > 0)
            {
                tTick.Interval = i;
                IsSuccessFlag = true;
            }
            e.Result = btn;
        }

        private delegate void GetMessage(byte[] bs);

        private BackgroundWorker backWorker = null;

        void txtSTime_KeyPress(object sender, KeyPressEventArgs e)
        {
            TextBox txtbox = sender as TextBox;
            if (txtbox.Font != txtHost.Font)
            {
                txtbox.Font = txtHost.Font;
            }
        }
        
        void timer_Tick(object sender, EventArgs e)
        {
            lblTime.Text = DateTime.Now.ToString();
        }

        void btnGet_Click(object sender, EventArgs e)
        {
            if (!btnGet.Enabled)
            {
                return;
            }
            lblState.Text = string.Format("无回复数据！");
            btnGet.Enabled = false;
            btnSet.Enabled = false;

            backWorker.RunWorkerAsync(sender);
        }

        void txtHost_LostFocus(object sender, EventArgs e)
        {
            TextBox txtbox = sender as TextBox;
            if (txtbox.Name == txtHost.Name)
            {
                if (!IPAddress.TryParse(txtbox.Text, out ipAddr))
                {
                    ipAddr = IPAddress.Parse("10.66.166.16");
                    txtbox.Text = ipAddr.ToString();
                    MessageBox.Show("输入IP地址不正确！");
                    return;
                }
            }
            else if (txtbox.Name == txtSendPort.Name)
            {
                if (!int.TryParse(txtbox.Text, out iSourcePort))
                {
                    iSourcePort = 8001;
                    txtbox.Text = iSourcePort.ToString();
                    MessageBox.Show("输入端口号不正确！");
                    return;
                }
                if (iSourcePort < 1 || iSourcePort > 65535)
                {
                    txtbox.Text = string.Format("8089");
                    MessageBox.Show("输入端口号不正确！");
                    return;
                }
            }
            else if (txtbox.Name == txtRecPort.Name)
            {
                if (!int.TryParse(txtbox.Text, out iRemotePort))
                {
                    iSourcePort = 8990;
                    txtbox.Text = iRemotePort.ToString();
                    MessageBox.Show("输入端口号不正确！");
                    return;
                }
                if (iRemotePort < 1 || iSourcePort > 65535)
                {
                    txtbox.Text = string.Format("8990");
                    MessageBox.Show("输入端口号不正确！");
                    return;
                }
            }
            else if (txtbox.Name == txtSTime.Name)
            {
                int iTic = 40;
                if (!int.TryParse(txtbox.Text, out iTic))
                {
                    iTick = 30;
                    txtSTime.Text = string.Format("{0}", Math.Round(iTick * 4d / 3d, 0));
                    MessageBox.Show("输入曝光时间不正确！");
                    return;
                }
                if (iTic < 2 || iTic > 340)
                {
                    iTick = 30;
                    txtSTime.Text = string.Format("{0}", Math.Round(iTick * 4d / 3d, 0));
                    MessageBox.Show("输入曝光时间不正确！");
                    return;
                }
                iTick=(byte)(iTic*3/4);
            }
            else if (txtbox.Name == txtPNum.Name)
            {
                int ipack = 1500;
                if (!int.TryParse(txtbox.Text, out ipack))
                {
                    iPackage = 500;
                    txtPNum.Text = string.Format("{0}", Math.Round(750000d / iPackage, 0));
                    MessageBox.Show("输入每秒包数不正确！");
                    return;
                }
                if (ipack<12||ipack>5000)
                {
                    iPackage = 500;
                    txtPNum.Text = string.Format("{0}", Math.Round(750000d / iPackage, 0));
                    MessageBox.Show("输入每秒包数不正确！");
                    return;
                }
                iPackage=(UInt16)(750000/ipack);
            }
        }
    }
}
